package com.tduck.cloud.datav.service;


import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.lang.TypeReference;
import cn.hutool.core.map.MapUtil;
import com.google.common.collect.Lists;
import com.tduck.cloud.datav.constant.ChartsConstants;
import com.tduck.cloud.datav.request.ChartDataRequest;
import com.tduck.cloud.datav.vo.EchartsSeriesVO;
import com.tduck.cloud.datav.vo.GroupQueryResult;
import com.tduck.cloud.report.data.params.GroupQueryParams;
import com.tduck.cloud.report.data.template.DataSearchTemplate;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import static com.tduck.cloud.report.data.template.MongoDataSearchTemplateImpl.MONGODB_ID;

/**
 * 基础图标数据服务
 *
 * @author tduck
 */
public abstract class BaseChartDataService {


    @Autowired
    protected DataSearchTemplate dataSearchTemplate;


    /**
     * 获取图表数据
     *
     * @param request 请求
     * @return 图标所需数据格式
     */
    public abstract Map<String, Object> getChartData(ChartDataRequest request);


    /**
     * 默认echarts数据
     *
     * @param request 请求参数
     */
    protected Map<String, Object> getEChartsData(ChartDataRequest request) {
        if (CollUtil.isEmpty(request.getDimension())) {
            return MapUtil.newHashMap();
        }
        GroupQueryResult groupQueryResult = this.getGroupQueryDataList(request);
        Map<String, Object> result = MapUtil.of();
        result.put(ChartsConstants.CATEGORIES, groupQueryResult.getGroupDataList());
        Map<String, List<Object>> groupAggsMap = groupQueryResult.getGroupAggsMap();
        if(MapUtil.isEmpty(groupAggsMap)){
            return result;
        }
        List<EchartsSeriesVO> seriesVOList = groupAggsMap.keySet().stream().map(key -> {
            EchartsSeriesVO echartsSeriesVO = new EchartsSeriesVO(key, groupAggsMap.get(key));
            request.getIndex().stream().filter(item -> key.startsWith(item.getId())).findFirst().ifPresent(item -> echartsSeriesVO.setName(item.getLabel()));
            return echartsSeriesVO;
        }).collect(Collectors.toList());
        result.put(ChartsConstants.SERIES, seriesVOList);
        return result;
    }

    /**
     * 查询数据
     *
     * @param request 参数
     */
    protected GroupQueryResult getGroupQueryDataList(ChartDataRequest request) {
        List<GroupQueryParams.GroupField> groupFieldList = request.getDimension().stream().map(item -> new GroupQueryParams.GroupField(item.getId(), null != item.getDateFormat() ? item.getDateFormat().getFormat() : "")).collect(Collectors.toList());
        List<GroupQueryParams.AggregateField> fieldList = request.getIndex().stream().map(item -> new GroupQueryParams.AggregateField(item.getId(), item.getAggregateType())).collect(Collectors.toList());
        GroupQueryParams params = new GroupQueryParams();
        params.setGroupByFields(groupFieldList);
        params.setFilter(Lists.newArrayList(request.getFilter()));
        params.setAggregateFields(fieldList);
        params.setQueryObjName(request.getIndexName());
        params.setLimit(request.getLimit());
        params.setSortFields(request.getSorts());
        List<Map> mappedResults = dataSearchTemplate.groupQuery(params);
        if(CollUtil.isEmpty(mappedResults)){
            return new GroupQueryResult();
        }
        // 组装数据 给前端使用
        Map<String, List<Object>> groupAggsMap = new HashMap<>();
        for (Map mappedResult : mappedResults) {
            for (Object o : mappedResult.keySet()) {
                String key = o.toString();
                if (key.equals(MONGODB_ID)) {
                    continue;
                }
                if (!groupAggsMap.containsKey(key)) {
                    groupAggsMap.put(key, CollUtil.toList(mappedResult.get(key)));
                } else {
                    groupAggsMap.get(key).add(mappedResult.get(key));
                }
            }
        }
        List<String> groupList = mappedResults.stream().map(item -> {
            // 多个分组字段 会是一个map
            if (item.get(MONGODB_ID) instanceof Map) {
                return CollUtil.join(MapUtil.getQuietly(item, MONGODB_ID, new TypeReference<Map<String, Object>>() {
                }, null).values(), "-");
            } else {
                return MapUtil.getStr(item, MONGODB_ID);
            }
        }).collect(Collectors.toList());
        return new GroupQueryResult(groupList, groupAggsMap);
    }





}
